/*
 * Indiana University Community Grid Computing Lab Software License,Version 1.1
 *
 * Copyright (c) 2002 Community Grid Computing Lab, Indiana University. 
 * All rights reserved.		
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *      "This product includes software developed by the Indiana University 
 *       Community Grid Computing Lab (http://www.communitygrids.iu.edu/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Indiana Univeristy","Indiana Univeristy Pervasive Techonology
 *    Labs" and  "Indiana Univeristy Community Grid Computing Lab" must not be
 *    used to endorse or promote products derived from this software without 
 *    prior written permission. For written permission, please contact 
 *    http://www.communitygrids.iu.edu/.
 *
 * 5. Products derived from this software may not use "Indiana
 *    University" name nor may "Indiana University" appear in their name,
 *    without prior written permission of the Indiana University.
 *
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
 * INDIANA UNIVERSITY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package cgl.sensorgrid.sopac.gps.threadpool;

import java.lang.reflect.*;
import java.util.*;

import cgl.hpsearch.engine.URIBindings.*;
import cgl.narada.event.*;
import cgl.narada.matching.*;
import cgl.narada.service.*;
import cgl.narada.service.client.*;

public class FilterRunner implements NBEventListener {

    private static ThreadPool pool = new ThreadPool(10);
    private String hostName;
    private String portNum;
    private String ryoTopic;
    private ClientService clientService;
    private EventConsumer consumer;
    private Profile profile;
    private NBNativeStreamHandler nbStream;
    private String filterName;

    public FilterRunner() {
    }


    public FilterRunner(String filterName,
                        String hostName,
                        String portNum,
                        String ryoTopic,
                        String asciiTopic) {
        try {
            this.filterName = filterName;
            this.hostName = hostName;
            this.portNum = portNum;
            this.ryoTopic = ryoTopic;
            String endpoint = "niotcp://" + hostName + ":" + portNum +
                              asciiTopic;
            this.nbStream = new NBNativeStreamHandler(endpoint);

            clientService = SessionService.getClientService((int) (System.
                    currentTimeMillis()));
        } catch (ServiceException ex) {
            ex.printStackTrace();
        }
    }

    public void stopConnection() {
        try {
            this.stopConnection();
            this.closeBrokerConnection();
        } catch (ServiceException ex) {
            ex.printStackTrace();
        }
    }

    public void initializeSubscriber() {
        Properties props = new Properties();
        props.put("hostname", this.hostName);
        props.put("portnum", this.portNum);
        try {
            initializeBrokerCommunications(props, "niotcp");
            initializeConsumer(this.ryoTopic);
        } catch (ServiceException serEx) {
            System.out.println(serEx);
        }
    }

    public void initializeBrokerCommunications(Properties props,
                                               String commType) throws
            ServiceException {
        clientService.initializeBrokerCommunications(props, commType);
    }

    public void initializeConsumer(String topic) throws ServiceException {
        profile =
                clientService.createProfile(TemplateProfileAndSynopsisTypes.
                                            STRING,
                                            topic);
        consumer = clientService.createEventConsumer(this);
        consumer.subscribeTo(profile);
    }

    /**
     *
     * @param nbEvent NBEvent
     */
    public void onEvent(NBEvent nbEvent) {
        if (nbEvent.getContentPayload() != null) {
            if (nbEvent != null) {
                //pool.assign(new ryo2ascii(nbStream, nbEvent));
                //pool.assign(new ryo2pos(nbStream, nbEvent));
                //pool.assign(new SingleStation(nbStream, nbEvent, "FVPK"));
                // pool.assign(new CalcDisplacement(nbStream, nbEvent));

                try {

                    String p = "FVPK";
                    Class c = Class.forName(this.filterName);
                    //Class[] params = {NBNativeStreamHandler.class, NBEvent.class};


                    Constructor ctorlist[]
                            = c.getDeclaredConstructors();
                    Class[] params = null;
                    for (int i = 0; i < ctorlist.length; i++) {
                        Constructor ct = ctorlist[i];
                        Class pvec[] = ct.getParameterTypes();
                        params = new Class[pvec.length];
                        for (int j = 0; j < pvec.length; j++) {
                            params[j] = pvec[j];
                        }
                    }

                    Constructor con = c.getDeclaredConstructor(params);
                    Object[] values = {nbStream, nbEvent, p};
                    pool.assign((Runnable) con.newInstance(values));
                    //Class pvec[] = con.getParameterTypes();
                    //for (int j = 0; j < pvec.length; j++)
                    //System.out.println("param #" + j + " " + pvec[j]);


                } catch (Exception ex) {
                    ex.printStackTrace();
                }

            }
        }
    }

    public void closeBrokerConnection() throws ServiceException {
        clientService.closeBrokerConnection();
        clientService.terminateServices();
    }


    /**
     * Main entry point.
     *
     * @param args  No arguments are used.
     */
    public static void main(String args[]) {
        int subscriberEntityId = (int) (System.currentTimeMillis());
        FilterRunner test = new FilterRunner(
                "cgl.sensorgrid.sopac.gps.filters.ryo2pos",
                "mastar.ucs.indiana.edu",
                "3045",
                "/SOPAC/GPS/Positions/5010/POS",
                "/SOPAC/GPS/Positions/5010/FVPK");

        test.initializeSubscriber();
        pool.complete();
        System.out.println("All tasks are done.");

    }
}
